package main

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"net/rpc"
	"time"
)

type RPCCall struct{}

func (r *RPCCall) Add(args *int, reply *int) error {
	*reply = *args
	return nil
}

func StartHTTPRPCServer() {
	call := new(RPCCall)
	serve := rpc.NewServer()
	serve.Register(call)
	serve.HandleHTTP("/rpc", "/debug/rpc")

	l, e := net.Listen("tcp", ":18080")
	if e != nil {
		log.Fatal("listen error:", e)
	}
	go http.Serve(l, nil)
}

func StartTCPRPCServer() {
	call := new(RPCCall)
	serve := rpc.NewServer()
	serve.Register(call)
	l, e := net.Listen("tcp", ":18081")
	if e != nil {
		log.Fatal("listen error:", e)
	}
	go serve.Accept(l)
}

func main() {

	// Start Server
	StartTCPRPCServer()
	StartHTTPRPCServer()

	time.Sleep(1000 * time.Millisecond)

	// HTTP RPC
	c1, _ := rpc.DialHTTPPath("tcp", "127.0.0.1:18080", "/rpc")
	var reply1 int
	fmt.Println(reply1)
	c1.Call("RPCCall.Add", 1000, &reply1)
	fmt.Println(reply1)

	// TCP RPC
	c2, _ := rpc.Dial("tcp", "127.0.0.1:18081")
	var reply2 int
	fmt.Println(reply2)
	c2.Call("RPCCall.Add", 1234, &reply2)
	fmt.Println(reply2)

	time.Sleep(1000 * time.Millisecond)
}
